package wizard;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.HashMap;

import javax.swing.Icon;

/**
 * 
 * @author michau
 *
 */

/**
 * model for the wizard, takes care of text, icons, and state of buttons
 * and of which panel is being displayed
 *
 */

public class WizardModel {
	//identification strings for elements
    public static final String CURRENT_PANEL_DESCRIPTOR_PROPERTY = "currentPanelDescriptorProperty";
     
    public static final String BACK_BUTTON_TEXT_PROPERTY = "backButtonTextProperty";
    
    public static final String BACK_BUTTON_ICON_PROPERTY = "backButtonIconProperty";
    
    public static final String BACK_BUTTON_ENABLED_PROPERTY = "backButtonEnabledProperty";
    
    public static final String NEXT_FINISH_BUTTON_TEXT_PROPERTY = "nextButtonTextProperty";
    
    public static final String NEXT_FINISH_BUTTON_ICON_PROPERTY = "nextButtonIconProperty";
    
    public static final String NEXT_FINISH_BUTTON_ENABLED_PROPERTY = "nextButtonEnabledProperty";
        
    public static final String CANCEL_BUTTON_TEXT_PROPERTY = "cancelButtonTextProperty";
    
    public static final String CANCEL_BUTTON_ICON_PROPERTY = "cancelButtonIconProperty";
    
    public static final String CANCEL_BUTTON_ENABLED_PROPERTY = "cancelButtonEnabledProperty";

    private WizardPanelDescriptor currentPanel;
    
    private HashMap panelHashmap;
    
    private HashMap<String, String> buttonTextHashmap;
    private HashMap<String, Icon> buttonIconHashmap;
    private HashMap<String, Boolean> buttonEnabledHashmap;
    
    private PropertyChangeSupport propertyChangeSupport;
    
    /**
     * Default constructor.
     */    
    public WizardModel() {
        
        panelHashmap = new HashMap();
        
        buttonTextHashmap = new HashMap<String, String>();
        buttonIconHashmap = new HashMap<String, Icon>();
        buttonEnabledHashmap = new HashMap<String, Boolean>();
        
        propertyChangeSupport = new PropertyChangeSupport(this);
    }
    
    /**
     * 
     * @return currently displayed panel
     */
    WizardPanelDescriptor getCurrentPanelDescriptor(){
    	return currentPanel;
    }
    
    /**
     * Registers new panel (puts it in the dictionary/hashtable)
     * @param id Object-based identifier (usually String)
     * @param descriptor Panel
     */
    void registerPanel(Object id, WizardPanelDescriptor descriptor){
    	panelHashmap.put(id, descriptor);
    }
    
    /**
     * Sets the appropriate panel as a current one (the one to be displayed).
     * @param id Object-based identifier (usually String)
     * @return Boolean value success/failure
     * @throws WizardPanelNotFoundException 
     */
    boolean setCurrentPanel(Object id) throws WizardPanelNotFoundException{
    	WizardPanelDescriptor nextPanel = (WizardPanelDescriptor) panelHashmap.get(id);
    	if (nextPanel == null)
    		throw new WizardPanelNotFoundException();
    	
    	WizardPanelDescriptor oldPanel = currentPanel;
    	currentPanel = nextPanel;
    	
    	// if the panel indeed changed
    	if (oldPanel != currentPanel)
    		firePropertyChange(CURRENT_PANEL_DESCRIPTOR_PROPERTY, oldPanel, currentPanel);
    	
    	return true;
    }
    
    // setters and getters for buttons
    String getBackButtonText() {
        return buttonTextHashmap.get(BACK_BUTTON_TEXT_PROPERTY);
    }
    
    void setBackButtonText(String newText) {
        
        String oldText = getBackButtonText();        
        if (!newText.equals(oldText)) {
            buttonTextHashmap.put(BACK_BUTTON_TEXT_PROPERTY, newText);
            firePropertyChange(BACK_BUTTON_TEXT_PROPERTY, oldText, newText);
        }
    }

    String getNextFinishButtonText() {
        return buttonTextHashmap.get(NEXT_FINISH_BUTTON_TEXT_PROPERTY);
    }
    
    void setNextFinishButtonText(String newText) {
        
        String oldText = getNextFinishButtonText();        
        if (!newText.equals(oldText)) {
            buttonTextHashmap.put(NEXT_FINISH_BUTTON_TEXT_PROPERTY, newText);
            firePropertyChange(NEXT_FINISH_BUTTON_TEXT_PROPERTY, oldText, newText);
        }
    }

    String getCancelButtonText() {
        return buttonTextHashmap.get(CANCEL_BUTTON_TEXT_PROPERTY);
    }
    
    void setCancelButtonText(String newText) {
        
        String oldText = getCancelButtonText();        
        if (!newText.equals(oldText)) {
            buttonTextHashmap.put(CANCEL_BUTTON_TEXT_PROPERTY, newText);
            firePropertyChange(CANCEL_BUTTON_TEXT_PROPERTY, oldText, newText);
        }
    } 
    
    Icon getBackButtonIcon() {
        return buttonIconHashmap.get(BACK_BUTTON_ICON_PROPERTY);
    }
    
    void setBackButtonIcon(Icon newIcon) {
        
        Icon oldIcon = getBackButtonIcon();        
        if (!newIcon.equals(oldIcon)) {
            buttonIconHashmap.put(BACK_BUTTON_ICON_PROPERTY, newIcon);
            firePropertyChange(BACK_BUTTON_ICON_PROPERTY, oldIcon, newIcon);
        }
    }

    Icon getNextFinishButtonIcon() {
        return buttonIconHashmap.get(NEXT_FINISH_BUTTON_ICON_PROPERTY);
    }
    
    public void setNextFinishButtonIcon(Icon newIcon) {
        
        Icon oldIcon = getNextFinishButtonIcon();        
        if (!newIcon.equals(oldIcon)) {
            buttonIconHashmap.put(NEXT_FINISH_BUTTON_ICON_PROPERTY, newIcon);
            firePropertyChange(NEXT_FINISH_BUTTON_ICON_PROPERTY, oldIcon, newIcon);
        }
    }

    Icon getCancelButtonIcon() {
        return buttonIconHashmap.get(CANCEL_BUTTON_ICON_PROPERTY);
    }
    
    void setCancelButtonIcon(Icon newIcon) {
        
        Icon oldIcon = getCancelButtonIcon();        
        if (!newIcon.equals(oldIcon)) {
            buttonIconHashmap.put(CANCEL_BUTTON_ICON_PROPERTY, newIcon);
            firePropertyChange(CANCEL_BUTTON_ICON_PROPERTY, oldIcon, newIcon);
        }
    } 
        
    
    Boolean getBackButtonEnabled() {
        return buttonEnabledHashmap.get(BACK_BUTTON_ENABLED_PROPERTY);
    }
    
    void setBackButtonEnabled(Boolean newValue) {
        
        Boolean oldValue = getBackButtonEnabled();        
        if (newValue != oldValue) {
            buttonEnabledHashmap.put(BACK_BUTTON_ENABLED_PROPERTY, newValue);
            firePropertyChange(BACK_BUTTON_ENABLED_PROPERTY, oldValue, newValue);
        }
    }

    Boolean getNextFinishButtonEnabled() {
        return buttonEnabledHashmap.get(NEXT_FINISH_BUTTON_ENABLED_PROPERTY);
    }
    
    void setNextFinishButtonEnabled(Boolean newValue) {
        
        Boolean oldValue = getNextFinishButtonEnabled();        
        if (newValue != oldValue) {
            buttonEnabledHashmap.put(NEXT_FINISH_BUTTON_ENABLED_PROPERTY, newValue);
            firePropertyChange(NEXT_FINISH_BUTTON_ENABLED_PROPERTY, oldValue, newValue);
        }
    }
    
    Boolean getCancelButtonEnabled() {
        return buttonEnabledHashmap.get(CANCEL_BUTTON_ENABLED_PROPERTY);
    }
    
    void setCancelButtonEnabled(Boolean newValue) {
        
        Boolean oldValue = getCancelButtonEnabled();        
        if (newValue != oldValue) {
            buttonEnabledHashmap.put(CANCEL_BUTTON_ENABLED_PROPERTY, newValue);
            firePropertyChange(CANCEL_BUTTON_ENABLED_PROPERTY, oldValue, newValue);
        }
    }
        
    public void addPropertyChangeListener(PropertyChangeListener p) {
        propertyChangeSupport.addPropertyChangeListener(p);
    }
    
    public void removePropertyChangeListener(PropertyChangeListener p) {
        propertyChangeSupport.removePropertyChangeListener(p);
    }
    
    protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
        propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
    }
 
}
